package com.waidi.clothespad.common;


import android.util.Log;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
/**
 * Created by ll on 2018/1/6.
 */

public final class HttpDownFile {

    private static String TAG = "HttpDownFile";
    private static HttpURLConnection lastConnCache = null;


    public HttpDownFile()
    {


    }
    /**
     * 从网络Url中下载文件
     *
     * @param urlStr
     * @param fileName
     * @param savePath
     * @throws IOException
     */
    public static void downLoadFromUrl(String urlStr, String fileName, String savePath) throws IOException {
        try {
                URL url = new URL(urlStr);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                if(lastConnCache==null)
                {
                    lastConnCache = conn;
                }
                else
                {
                    lastConnCache.disconnect(); //断开上次的下载
                    lastConnCache= null;
                    lastConnCache = conn;
                }


                //设置超时间为3秒
                conn.setConnectTimeout(3 * 1000);
                //防止屏蔽程序抓取而返回403错误
                conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");

                //得到输入流
                InputStream inputStream = conn.getInputStream();
                //写入文件
                savePath = savePath+"/"+fileName;
                Log.i(TAG,"download file :"+savePath);

                OutputStream os = new FileOutputStream(savePath);
                int length;
                byte [] bytes = new byte[1024*4];
                while ((length = inputStream.read(bytes))!= -1)
                {
                    os.write(bytes,0,length);
                    //获取当前进度值
                    //length=+length;
                    Log.i(TAG,Integer.toString(length));
                }
                //关闭流
                inputStream.close();
                os.close();
                os.flush();
                conn.disconnect();
                lastConnCache = null;

                if (inputStream != null) {
                    inputStream.close();
                }
                Log.i(TAG,"info:" + url + " 下载成功"+ " "+savePath);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    /**
     * HttpURLConnection 断点下载
     *
     * @param
     * @return
     * @throws IOException
     */
    public void BreakpointDownload(String urlStr, String fileName, String savePath) throws IOException, InterruptedException{
        //创建URL对象
        URL url = new URL(urlStr);
        //使用url获取HttpURLConnection对象
        HttpURLConnection conn = (HttpURLConnection)url.openConnection();
        //客户端的请求方式
        conn.setRequestMethod("GET");
        //已经下载的字节数
        long alreadySize = 0;
        //将文件写到d:\kiss.avi中
        //写入文件
        savePath = savePath+"/"+fileName;
        File file = new File(savePath);

        //如果存在，说明原来下载过，不过可能没有下载完
        if(file.exists()){
            //如果文件存在，就获取当前文件的大小
            alreadySize = file.length();
        }
        /**
         * Range头域可以请求实体的一个或者多个子范围。
         * 		例如:	表示头500个字节：bytes=0-499 　　
         *	    	 	表示第二个500字节：bytes=500-999 　　
         *     		 	表示最后500个字节：bytes=-500 　　
         *	     	 	表示500字节以后的范围：bytes=500- 　　
         *	     	 	第一个和最后一个字节：bytes=0-0,-1 　　
         *           	同时指定几个范围：bytes=500-600,601-999 　　
         * 但是服务器可以忽略此请求头，如果无条件GET包含Range请求头，响应会以状态码206（PartialContent）返回而不是以200 （OK）。
         */
        conn.addRequestProperty("Range", "bytes=" + alreadySize + "-");
        conn.connect();

        //206,一般表示断点续传
        //获取服务器回馈的状态码
        int code = conn.getResponseCode();
        // 如果响应成功，因为使用了range请求头，那么响应成功的状态码为206，而不是200
        if(code == 206){
            //获取未下载的文件的大小
            // 本方法用来获取响应正文的大小，但因为设置了range请求头，那么这个方法返回的就是剩余的大小
            long unfinishedSize = conn.getContentLength();
            //文件的大小
            long size = alreadySize + unfinishedSize;

            //获取输入流
            InputStream in = conn.getInputStream();
            //获取输出对象,参数一：目标文件，参数2表示在原来的文件中追加
            OutputStream out = new BufferedOutputStream(new FileOutputStream(file,true));

            //开始下载
            byte[] buff = new byte[2048];
            int len;
            StringBuilder sb = new StringBuilder();
            while((len = in.read(buff)) != -1){
                out.write(buff, 0, len);
                //将下载的累加到alreadSize中
                alreadySize += len;
                //下载进度
                //System.out.printf("%.2f%%\n", alreadySize * 1.0 / size * 100);
                Log.i(TAG,"已经下载文件长度："+alreadySize);
                //由于文件大小可以看得到，那么我们这里使用阻塞
                Thread.sleep(2);
            }
            out.close();
            Log.i(TAG,"下载完成！！！");
        }else{
            Log.i(TAG,"下载失败,返回code:"+code);
        }


        //断开连接
        conn.disconnect();
    }



    /**
     * 从输入流中获取字节数组
     *
     * @param inputStream
     * @return
     * @throws IOException
     */
    public static byte[] readInputStream(InputStream inputStream) throws IOException {
        byte[] buffer = new byte[1024];
        int len = 0;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while ((len = inputStream.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
            Log.i(TAG,Integer.toString(len));
        }
        bos.close();
        return bos.toByteArray();
    }











}
